package gui;

import generated.business.connection.ExistUserException;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

import vworld.Client;

public class LoginDialog {

	private static Text txt_Password;
	private static Text txt_Username;
	private Text txt_hostString;
	private Text txt_portString;
	private Display display;
	private Shell shell;
	private boolean isValid = false;
	private Region region;

	public LoginDialog(Display display) {
		this.display = display;
	}

	public void createContents() {
		shell = new Shell(display, SWT.CLOSE);
		shell.setText("VWorld Client");
		shell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		final FillLayout shellFillLayout = new FillLayout();
		shellFillLayout.marginHeight = 1;
		shell.setLayout(shellFillLayout);

		final Composite composite = new Composite(shell, SWT.NONE);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		composite.setLayout(gridLayout);

		final Label img_Label = setImage(composite); // Image is set
		final Composite cmp_Login = new Composite(composite, SWT.NONE);
		cmp_Login.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		final RowLayout rowLayout = new RowLayout();
		rowLayout.fill = true;
		cmp_Login.setLayout(rowLayout);
		final GridData gridData = new GridData(GridData.FILL, GridData.FILL,
				false, false);
		// gridData.widthHint = 196;
		gridData.widthHint = 250;
		cmp_Login.setLayoutData(gridData);

		createLoginLabel(cmp_Login);
		createUserNameLabel(cmp_Login);
		createUserNameText(cmp_Login);
		createPwdLabel(cmp_Login);
		createPwdText(cmp_Login);
		createHostLabel(cmp_Login);
		createHostText(cmp_Login);
		createPortLabel(cmp_Login);
		createPortText(cmp_Login);

		txt_hostString.setText("localhost");
		txt_portString.setText("900");

		final Label loginMessage = new Label(cmp_Login, SWT.NONE);
		loginMessage.setText("				");
		loginMessage.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
		loginMessage.setBackground(display.getSystemColor(SWT.COLOR_WHITE));

		final Composite cmp_ButtonBar = new Composite(cmp_Login, SWT.NONE);
		GridLayout gridLayout_2 = new GridLayout();
		gridLayout_2.numColumns = 2;
		cmp_ButtonBar.setLayout(gridLayout_2);
		cmp_ButtonBar.setBackground(display.getSystemColor(SWT.COLOR_WHITE));

		region = new Region();
		final Button btn_login = createLoginButton(cmp_ButtonBar);

		btn_login.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {

				Client.ORB = null;
				if (Client.ORB == null) {
					Client.initORB(txt_hostString.getText(), txt_portString
							.getText());
				}

				try {
					boolean connectionAuthorized = Client.CONNECTION_SERVICE
							.login(txt_Username.getText(), txt_Password
									.getText());
					if (!connectionAuthorized) {
						loginMessage.setText("Invalid login and/or password");
						loginMessage.setForeground(display
								.getSystemColor(SWT.COLOR_RED));
					} else {
						Client.CONNECTED_USER = Client.CONNECTION_SERVICE
								.getConnectedUser();
						Client.registerClientCallbackServant();
						Client.CONNECTION_SERVICE.registerClient(
								Client.CONNECTED_USER.login,
								Client.CALL_BACK_REF);

						isValid = true;
					}
				} catch (ExistUserException e) {
					MessageDialog.openError(Display.getCurrent()
							.getActiveShell(), "Error", e.reason);
					PlatformUI.getWorkbench().restart();
					e.printStackTrace();
				}
			}
		});

		final Button btn_register = createRegisterButton(cmp_ButtonBar);
		btn_register.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent event) {
			}

			public void widgetSelected(SelectionEvent event) {
				RegisterDialog registerDialog = new RegisterDialog(display);
				registerDialog.open();
			}
		});

		final CLabel clbl_Message = new CLabel(cmp_Login, SWT.NONE);
		clbl_Message.setAlignment(SWT.RIGHT);

		clbl_Message.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		final RowData rowData_6 = new RowData();
		rowData_6.width = 188;
		clbl_Message.setLayoutData(rowData_6);
		clbl_Message.setText("VWorld");

		Rectangle pixel = new Rectangle(1, 1, 388, 182);
		region.add(pixel);
		shell.setRegion(region);
		addDragListener(composite, img_Label, shell);

		shell.pack();
		shell.setMaximized(false);
		shell.open();
		shell.layout();

		// center on the screen
		Rectangle displayBounds = Display.getCurrent().getBounds();
		Point size = shell.getSize();
		int x = (displayBounds.width - size.x) / 2;
		int y = (displayBounds.height - size.y) / 2;
		shell.setLocation(x, y);
	}

	private Label setImage(Composite composite) {
		Label img_Label = new Label(composite, SWT.NONE);
		composite.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		img_Label.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		img_Label.setImage(ResourceManager.getPluginImage(Activator
				.getDefault(), "resources/images/img_login.bmp"));
		img_Label.setLayoutData(new GridData(195, 181));
		return img_Label;
	}

	private void createLoginLabel(Composite cmp_Login) {
		final CLabel clbl_UserLogin = new CLabel(cmp_Login, SWT.NONE);
		final RowData rowData = new RowData();
		rowData.width = 180;
		clbl_UserLogin.setLayoutData(rowData);
		clbl_UserLogin.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		clbl_UserLogin.setText("Login");
	}

	private void createUserNameLabel(Composite cmp_Login) {
		final CLabel clbl_Username = new CLabel(cmp_Login, SWT.NONE);
		final RowData rowData_1 = new RowData();
		rowData_1.width = 180;
		clbl_Username.setLayoutData(rowData_1);
		clbl_Username.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		clbl_Username.setText("Username");
	}

	private void createHostLabel(Composite cmp_Host) {
		final CLabel clbl_host = new CLabel(cmp_Host, SWT.NONE);
		final RowData rowData_1 = new RowData();
		rowData_1.width = 180;
		clbl_host.setLayoutData(rowData_1);
		clbl_host.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		clbl_host.setText("Host");
	}

	private void createPortLabel(Composite cmp_Port) {
		final CLabel clbl_port = new CLabel(cmp_Port, SWT.NONE);
		final RowData rowData_1 = new RowData();
		rowData_1.width = 180;
		clbl_port.setLayoutData(rowData_1);
		clbl_port.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		clbl_port.setText("Port");
	}

	private void createUserNameText(Composite cmp_Login) {
		txt_Username = new Text(cmp_Login, SWT.BORDER);
		final RowData rowData_2 = new RowData();
		rowData_2.width = 170;
		txt_Username.setLayoutData(rowData_2);
	}

	private void createPwdLabel(Composite cmp_Login) {
		final CLabel clbl_Password = new CLabel(cmp_Login, SWT.NONE);
		final RowData rowData_3 = new RowData();
		rowData_3.width = 180;
		clbl_Password.setLayoutData(rowData_3);
		clbl_Password.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		clbl_Password.setText("Password");
	}

	private void createPwdText(Composite cmp_Login) {
		txt_Password = new Text(cmp_Login, SWT.BORDER);
		final RowData rowData_4 = new RowData();
		rowData_4.width = 170;
		txt_Password.setLayoutData(rowData_4);
		txt_Password.setEchoChar('*');
	}

	private void createHostText(Composite cmp_Host) {
		txt_hostString = new Text(cmp_Host, SWT.BORDER);
		final RowData rowData_4 = new RowData();
		rowData_4.width = 170;
		txt_hostString.setLayoutData(rowData_4);
		// TODO change host?
		txt_hostString.setText("localhost");
	}

	private void createPortText(Composite cmp_Port) {
		txt_portString = new Text(cmp_Port, SWT.BORDER);
		final RowData rowData_4 = new RowData();
		rowData_4.width = 170;
		txt_portString.setLayoutData(rowData_4);
		// TODO change port?
		txt_portString.setText("900");
	}

	private Button createLoginButton(Composite cmp_ButtonBar) {
		final Button btn_login = new Button(cmp_ButtonBar, SWT.FLAT);
		GridData gridData_2 = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		btn_login.setLayoutData(gridData_2);
		btn_login.setText("Login");
		return btn_login;
	}

	private Button createRegisterButton(Composite cmp_ButtonBar) {
		final Button btn_register = new Button(cmp_ButtonBar, SWT.FLAT);
		GridData gridData_3 = new GridData(GridData.HORIZONTAL_ALIGN_END);
		btn_register.setLayoutData(gridData_3);
		btn_register.setText("Register");
		return btn_register;
	}

	public void addDragListener(Composite composite, Label img_Label,
			final Shell shell) {
		Listener l = new Listener() {
			Point origin;

			public void handleEvent(Event e) {
				switch (e.type) {
				case SWT.MouseDown:
					origin = new Point(e.x, e.y);
					break;
				case SWT.MouseUp:
					origin = null;
					break;
				case SWT.MouseMove:
					if (origin != null) {
						Point p = display.map(shell, null, e.x, e.y);
						shell.setLocation(p.x - origin.x, p.y - origin.y);
					}
					break;
				}
			}
		};

		composite.addListener(SWT.MouseDown, l);
		composite.addListener(SWT.MouseUp, l);
		composite.addListener(SWT.MouseMove, l);
		img_Label.addListener(SWT.MouseDown, l);
		img_Label.addListener(SWT.MouseUp, l);
		img_Label.addListener(SWT.MouseMove, l);
	}

	public void open() {
		while (!shell.isDisposed()) {
			if (isValid) {
				shell.dispose();
				break;
			}
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		region.dispose();
	}
}
